/* UC
 * FCyT
 * TP de SPD
 * Federico Gonzalez <fedegon7@gmail.com>
 * Lorena Figueredo <lorenafigueredo@gmail.com>
 * Fernando Cardozo <fercard06@gmail.com>,
 * Sergio Gonzalez <sergiogonzalezveron@gmail.com>
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <time.h>

#define PORT 3700 // puerto al que vamos a conectar


// http://www.arrakis.es/~dmrq/beej/faq.html#AEN1470
int recvtimeout(int s, char *buf, int len, int timeout)
{
    fd_set fds;
    int n;
    struct timeval tv;

    // Construir el conjunto de descriptores de fichero
    FD_ZERO(&fds);
    FD_SET(s, &fds);

    // Construir la estructura timeval del temporizador
    tv.tv_sec = timeout;
    tv.tv_usec = 0;

    // Esperar hasta que se reciban datos o venza el temporizador
    n = select(s+1, &fds, NULL, NULL, &tv);
    if (n == 0) return -2; // ¡El temporizador ha vencido!
    if (n == -1) return -1; // error

    // Los datos deben estar ahí, así que llamo normalmente a recv()
    return recv(s, buf, len, 0);
}


int main(int argc, char *argv[])
{
    int sockfd, numbytes;  
    struct hostent *he;
    struct sockaddr_in their_addr; // información de la dirección de destino
    char buffer_salida[1000] = {'\0'}; // lo que se va a enviar al servidor
    char buffer_entrada[1000] = {'\0'}; // verificar el tamanho, es mucho ya

    clock_t comienzo, final; //para marcar el tiempo inicial y final de respuesta

    printf("prueba de conexion\n"); // a quitar despues
    if (argc != 5) {
        fprintf(stderr, "uso: cliente num_telefono num_tarjeta_credito pin monto\n");
        exit(1);
    }
    
    comienzo = clock(); //se toma la hora inicial

    // esto esta mal, porque deberia ser la direccion del server, mientras es localhost
    if ((he=gethostbyname("localhost")) == NULL) {  // obtener información de máquina 
        perror("gethostbyname");
        exit(1);
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    their_addr.sin_family = AF_INET;    // Ordenación de bytes de la máquina
    their_addr.sin_port = htons(PORT);  // short, Ordenación de bytes de la red 
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(&(their_addr.sin_zero), '\0', 8);  // poner a cero el resto de la estructura 

    if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect");
        exit(1);
    }

    // aqui cargamos los datos
    sprintf(buffer_salida, "%s\n%s\n%s\n%s\n", argv[1], argv[2], argv[3], argv[4]);
    
    if (send(sockfd, buffer_salida, strlen(buffer_salida), 0) == -1)
        perror("send");

    numbytes = recvtimeout(sockfd, buffer_entrada, sizeof(buffer_entrada), 1); // 30 segundos de espera

    if (numbytes == -1) {
        // ocurrió un error
        perror("recvtimeout");
    }
    else if (numbytes == -2) {
        // El temporizador venció
        perror("ERROR DE COMUNICACION\n(el temporizador vencio)");
    }
    else if (numbytes == 0) {
        // cerro la conexion el servidor
        printf("Cerro la conexion el servidor\n");
    }
    else {
        // Hay datos en el buffer
        printf("Llego datos\n");
        if (!strcmp("OK", buffer_entrada))
            printf("ok\n");
        if (!strcmp("SIN_SALDO", buffer_entrada))
            printf("sin saldo\n");
        if (!strcmp("NRO_INEXISTENTE", buffer_entrada))
            printf("NRO_INEXISTENTE\n");
        printf(buffer_entrada);
    }

    close(sockfd);
    final = clock(); //tiempo final
    printf( "\nNúmero de segundos transcurridos desde para el envio: %f \n", difftime(final, comienzo)/ CLOCKS_PER_SEC );

    return (0);
}


